import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.util.*;

/**
 * Enemigo Class
 * @author Hugo Armando Rodíguez Flores
 * @version May 23th 2013
 */
public abstract class Enemigo extends Ninja
{
    private int move; //Type of move
    private int randomizeTiming; //A counter that blocks the randomizing of numbers
    private int detonationCounter;  //Counter that controls the detonations animation
    private ArrayList<GreenfootImage> detonations;   //This collection contains the detonation images
    private boolean removeFlag; //This flag determines wether the character's ready to explode
    private boolean attacked;   //True if some enemy has attacked
    private int attackTiming;   //Counter that controls the attack
    
    /**
     * Constructs a new Enemigo
     */
    public Enemigo()
    {
        detonations=new ArrayList<GreenfootImage>();
        String tempString=new String();
        for (int i=0; i<3; i++)
        {
            tempString="explosion"+(i+1)+".png";
            detonations.add(new GreenfootImage(tempString));
        }
        move=-1;
        attackTiming=detonationCounter=randomizeTiming=0;
        attacked=removeFlag=false;
    }
    
    /**
     * This moves the character and request a new direction.
     */
    public void act() 
    {
        this.randomizeCount();
        if (Greenfoot.getRandomNumber(4)==2)
            this.move();
    }
    
    /**
     * It counts till the reference is acomplished, then restarts the attacked flag
     * @param reference is the reference of the counter to put the flag back on false
     */
    public void attackTiming(int reference)
    {
        if (this.getAttackedFlag())
            if (this.getAttackTiming()==reference)
            {
                this.setAttackedFlag(false);
                this.setAttackTiming(0);
            }
            else
                this.attackTimingIncr();
    }
    
    /**
     * This checks whether an instance of Thomas class is in front of one to attack him.
     */
    public void thomasDetection(int cells)
    {
        Actor thomas=null;
        int val=-1;
        for (int i=0; i<cells; i++)
            if (!super.getDirection())
            {
                thomas=this.getOneObjectAtOffset(i*val, 0, Thomas.class);
                if (thomas!=null)
                    this.attack();
            }
            else
            {
                thomas=this.getOneObjectAtOffset(i, 0, Thomas.class);
                if (thomas!=null)
                    this.attack();
            }
    }
    
    /**
     * Puts the detonation sequence and deletes the enemy
     */
    public void removeEnemy()
    {
        switch (detonationCounter)
        {
            case 0: this.setImage(detonations.get(0));  detonationCounter++;  break;
            case 3: this.setImage(detonations.get(1));  detonationCounter++;  break;
            case 6: this.setImage(detonations.get(2));  detonationCounter++;  break;
            case 9: World world=getWorld(); world.removeObject (this);
            default: detonationCounter++;
        }
    }
    
    /**
     * Creates a number to determine in wich direction the character should be moving
     */
    public void randomizeCount()
    {
        if (randomizeTiming==30)
        {
            move=Greenfoot.getRandomNumber(4);
            randomizeTiming=0;
        }
        else
            randomizeTiming++;
    }
    
    /**
     * This moves an enemy, checks wether an instance of Decoracion is in front of him,
     */
    public void move()
    {
        Actor decPiece=null;
        switch (move)
        {
            case 0:
                decPiece=getOneObjectAtOffset(2, 0, Decoracion.class);
                if(decPiece==null)
                {
                    if (!super.getDirection())
                        super.setDirectionFlag(true);
                    super.setDirection(true);
                    super.realocate(1, 0);
                }
                break;//->
            case 1:
                decPiece=getOneObjectAtOffset(-2, 0, Decoracion.class);
                if(decPiece==null)
                {
                    if (super.getDirection())
                        super.setDirectionFlag(true);
                    super.setDirection(false);
                    super.realocate(-1, 0);
                }
                break;//<-
            case 2:
                decPiece=getOneObjectAtOffset(0, -6, Decoracion.class);
                if(decPiece==null)
                    super.realocate(0, -1);
                break;//up
            case 3:
                decPiece=getOneObjectAtOffset(0, 1, Decoracion.class);
                if(decPiece==null)
                    super.realocate(0, 1);
                break;//down
        }
    }
    
    /**
     * @return the remove flag
     */
    public boolean getRemoveFlag()
    {
        return removeFlag;
    }
    
    /**
     * Sets a value to the remove flag.
     * @param newFlag is the new value to be assigned to the remove flag
     */
    public void setRemoveFlag(boolean newFlag)
    {
        removeFlag=newFlag;
    }
    
    /**
     * @return the attacked flag.
     */
    public boolean getAttackedFlag()
    {
        return attacked;
    }
    
    /**
     * Sets a value to the attacked flag.
     * @param aFlag is the new value to be assigned to the attacked flag
     */
    public void setAttackedFlag(boolean aFlag)
    {
        attacked=aFlag;
    }
    
    /**
     * @return the attack counter
     */
    public int getAttackTiming()
    {
        return attackTiming;
    }
    
    /**
     * Sets a value to the counter.
     * @param anInteger is the new integer to be assigned to the attack counter
     */
    public void setAttackTiming(int anInteger)
    {
        attackTiming=anInteger;
    }
    
    /**
     * Increments the timer on one.
     */
    public void attackTimingIncr()
    {
        attackTiming++;
    }
}
